package com.haojiang.mh.widget.chart;

import android.content.Context;
import android.graphics.*;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.View;
import androidx.annotation.Nullable;
import com.haojiang.mh.R;
import com.haojiang.mh.service.entity.SleepTimeChartBean;
import com.haojiang.mh.service.entity.StartEndBean;
import com.haojiang.mh.utils.SizeUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

/**
 * 双X轴+Cover+间断圆角柱
 * 当前用在《周报--睡眠时间分布》
 */
public class WeekSleepTimeChartView extends View {

    private TextPaint textPaint;//文字画笔
    //背景、圆柱、点、线 画笔
    private Paint coverPaint, columnPaint, coordinatePaint, linePaint;
    //圆柱宽、X轴文本高、Y轴文本高、K线区高、X轴高、Y轴宽
    private int columnWidth, xAxisTextHeight, yAxisTextHeight, drawHeight, xAxisHeight, yAxisWidth, bottomY;
    private float xItemWidth, yItemHeight;
    private int xTextSize, yTextSize; //X轴、Y轴文本字体大小
    private LinearGradient shader;//渐变
    private String[] xAxisBottom, xAxisTop;//X轴上下文本集
    private int width, height, defaultWidth, defaultHeight;//当前View的宽高、默认宽高度
    private int workDayColor, weekendColor, coverColor, coverLineColor;//工作日、周末 文字颜色
    private int columnGraTopColor, columnGraBottomColor;//顶部、底部渐变颜色值
    private List<SleepTimeChartBean> beanList;//数据集
    private RectF rectF = new RectF();//矩形

    public WeekSleepTimeChartView(Context context) {
        this(context, null);
    }

    public WeekSleepTimeChartView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public WeekSleepTimeChartView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        columnWidth = SizeUtil.dp2px(context, 5);
        xAxisTextHeight = SizeUtil.dp2px(context, 30);
        yAxisTextHeight = SizeUtil.dp2px(context, 20);
        drawHeight = SizeUtil.dp2px(context, 150);
        xAxisHeight = SizeUtil.dp2px(context, 3);
        yAxisWidth = SizeUtil.dp2px(context, 30);

        xTextSize = SizeUtil.sp2px(context, 12);
        yTextSize = SizeUtil.sp2px(context, 10);

        defaultWidth = SizeUtil.dp2px(context, 340);
        defaultHeight = xAxisTextHeight + drawHeight + xAxisHeight + xAxisTextHeight;

        workDayColor = getResources().getColor(R.color.white_half);
        weekendColor = getResources().getColor(R.color.purple_3);
        columnGraTopColor = getResources().getColor(R.color.purple_3);
        columnGraBottomColor = getResources().getColor(R.color.purple_5);
        coverColor = getResources().getColor(R.color.grey_5) & 0x4CFFFFFF;
        coverLineColor = getResources().getColor(R.color.white) & 0x19FFFFFF;

        xAxisBottom = new String[]{"20", "21", "22", "23", "24", "25", "26"};
        xAxisTop = getResources().getStringArray(R.array.chinaWeekDayArray);

        textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
        textPaint.setTextAlign(Paint.Align.CENTER);

        coverPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        coverPaint.setStyle(Paint.Style.FILL);
        coverPaint.setColor(coverColor);

        coordinatePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        coordinatePaint.setStyle(Paint.Style.FILL);
        coordinatePaint.setColor(workDayColor);

        columnPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        columnPaint.setStyle(Paint.Style.FILL);

        linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        linePaint.setColor(coverLineColor);
        linePaint.setStrokeWidth(2);

    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        width = w;
        height = h;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        if (beanList == null || beanList.isEmpty()) return;
        xItemWidth = (float) (width - yAxisWidth) / xAxisTop.length;
        yItemHeight = (float) drawHeight / 24;
        bottomY = height - xAxisHeight - xAxisTextHeight;

        /* 绘制X轴 */
        drawXAxis(canvas);

        /* 绘制最佳睡眠区 */
        drawCover(canvas);

        /* 绘制Y轴 */
        drawYAxis(canvas);

        /* 绘制K线 */
        drawColumn(canvas);
    }

    /**
     * 绘制X轴
     */
    private void drawXAxis(Canvas canvas) {
        textPaint.setTextSize(xTextSize);
        for (int i = 0; i < xAxisTop.length; i++) {
            float xItemMidPosition = xItemWidth * i + xItemWidth * 0.5f;
            textPaint.setColor((i == 5 || i == 6) ? weekendColor : workDayColor);
            //上轴
            canvas.drawText(
                    xAxisTop[i],
                    xItemMidPosition,
                    SizeUtil.getBaseLine(textPaint, xAxisTextHeight, xAxisTextHeight),
                    textPaint
            );
            //下轴
            canvas.drawLine(
                    xItemMidPosition,
                    bottomY,
                    xItemMidPosition,
                    bottomY + xAxisHeight,
                    coordinatePaint
            );
            canvas.drawText(
                    xAxisBottom[i],
                    xItemMidPosition,
                    SizeUtil.getBaseLine(textPaint, height, xAxisTextHeight),
                    textPaint
            );
        }

    }

    /**
     * 绘制遮罩层
     */
    private void drawCover(Canvas canvas) {
        canvas.drawLine(0, xAxisTextHeight + 11 * yItemHeight, width, xAxisTextHeight + 11 * yItemHeight, linePaint);
        canvas.drawRect(0, xAxisTextHeight + 11 * yItemHeight, width, xAxisTextHeight + 20 * yItemHeight, coverPaint);
        canvas.drawLine(0, xAxisTextHeight + 20 * yItemHeight, width, xAxisTextHeight + 20 * yItemHeight, linePaint);
    }

    /**
     * 绘制Y轴
     */
    private void drawYAxis(Canvas canvas) {
        textPaint.setColor(workDayColor);
        textPaint.setTextSize(yTextSize);
        for (int i = 0; i < 25; i++) {//从上至下
            canvas.drawCircle(width - yAxisWidth, bottomY - yItemHeight * i, 3, coordinatePaint);
            if (i % 3 != 0) continue;
            float yTextBaseLine = bottomY - yItemHeight * i + yAxisTextHeight * 0.5f;
            canvas.drawText(
                    String.format(Locale.getDefault(), "%02d:00", (i + 18) % 24),
                    width - yAxisWidth * 0.5f,
                    SizeUtil.getBaseLine(textPaint, yTextBaseLine, yAxisTextHeight),
                    textPaint
            );
        }
    }

    /**
     * 绘制间断柱子
     */
    private void drawColumn(Canvas canvas) {
        int totalTime = 24 * 3600;
        for (int i = 0; i < beanList.size(); i++) {
            List<StartEndBean> list = beanList.get(i).getLine();
            if (list == null || list.isEmpty()) continue;
            float xItemMidPosition = xItemWidth * i + xItemWidth * 0.5f;
            float bottom = bottomY - list.get(0).getStart() * drawHeight * 1.0f / totalTime;
            float top = bottomY - list.get(list.size() - 1).getEnd() * drawHeight * 1.0f / totalTime;
            shader = new LinearGradient(0, bottom, 0, top, columnGraBottomColor, columnGraTopColor, Shader.TileMode.CLAMP);
            columnPaint.setShader(shader);
            for (int j = 0; j < list.size(); j++) {
                StartEndBean bean = list.get(j);
                if (bean.isNull()) continue;
                float itemBottom = bottomY - (bean.getStart() * drawHeight * 1.0f / totalTime);
                float itemTop = bottomY - (bean.getEnd() * drawHeight * 1.0f / totalTime);
                rectF.set(
                        xItemMidPosition - columnWidth * 0.5f,
                        itemTop,
                        xItemMidPosition + columnWidth * 0.5f,
                        itemBottom
                );
                canvas.drawRoundRect(rectF, columnWidth * 0.5f, columnWidth * 0.5f, columnPaint);
            }
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(
                getMeasuredLength(widthMeasureSpec, true),
                getMeasuredLength(heightMeasureSpec, false)
        );
    }

    private int getMeasuredLength(int length, boolean isWidth) {
        int specMode = MeasureSpec.getMode(length);
        int specSize = MeasureSpec.getSize(length);
        int size;
        int padding = isWidth ? getPaddingLeft() + getPaddingRight() : getPaddingTop() + getPaddingBottom();
        if (specMode == MeasureSpec.EXACTLY) {
            size = specSize;
        } else if (specMode == MeasureSpec.UNSPECIFIED) {
            size = isWidth ? defaultWidth : defaultHeight;
        } else {
            size = isWidth ? padding + defaultWidth : padding + defaultHeight;
            if (specMode == MeasureSpec.AT_MOST) {
                size = Math.min(size, specSize);
            }
        }
        return size;
    }

    public void setChartData(List<SleepTimeChartBean> data) {
        if (beanList == null) beanList = new ArrayList<>();
        beanList.clear();
        if (data != null && !data.isEmpty()) {
            beanList.addAll(data);
            for (int i = 0; i < beanList.size(); i++) {
                xAxisBottom[i] = beanList.get(i).getDay();
            }
        }
        invalidate();
    }
}

